设计模式之单例模式 (设计模式之单例模式PPT)

本文目录导航:

设计模式之单例模式

单例设计模式理解起来非常简单。

一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫单例模式。

设计模式之单例模式 (设计模式之单例模式PPT)

下面的示例中如果每个类都创建一个 Logger 实例,就可能造成日志内容被覆盖的情况。

如果有些数据在系统中只应保存一份,那就比较适合设计为单例类。

比如,配置信息类,全局 ID 生成器等。

要实现一个单例,我们要考虑以下几点:

懒汉式相对于饿汉式的优势是「支持延迟加载」 。

但缺点也很明显,因为使用了 synchronized 关键字导致这个方法的「并发度很低」 。

如果这个单例类偶尔会被用到,那这种实现方式还可以接受。

但是,如果频繁地用到,就会导致性能瓶颈,这种实现方式就不可取了。

这是一种既支持延迟加载、又支持高并发的单例实现方式。

在 java1.5 以下 instance = new Singleton(); 有指令重排问题,需要给 instance 成员变量加上 volatile 关键字,java1.5 之后不会再这个问题。

这种方式利用了 Java 的静态内部类,有点类似饿汉式,但又能做到了延迟加载。

当外部类 Singleton 被加载的时候,并不会创建 SingletonHolder 实例对象。

只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。

insance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。

所以,这种实现方法既保证了线程安全,又能做到延迟加载。

这是一种最简单的实现方式,基于枚举类型的单例实现。

这种实现方式是通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。

上面的单例类对象是进程唯一的,一个进程只能有一个单例对象。那如何实现一个线程唯一的单例呢?

假设 IdGenerator 是一个线程唯一的单例类。

在线程 A 内,我们可以创建一个单例对象 a。

因为线程内唯一,在线程 A 内就不能再创建新的 IdGenerator 对象了,而线程间可以不唯一,所以,在另外一个线程 B 内,我们还可以重新创建一个新的单例对象 b。

我们通过一个 ConcurrentHashMap 来存储对象,其中 key 是线程 ID,value 是对象。

这样我们就可以做到,不同的线程对应不同的对象,同一个线程只能对应一个对象。

实际上,Java 语言本身提供了 ThreadLocal 工具类,可以更加轻松地实现线程唯一单例。

如何在Java中实现单例模式?

单例模式大致有五种写法,分别为懒汉,恶汉,静态内部类,枚举和双重校验锁。

1、懒汉写法,常用写法

如何在java中实现singleton模式

单例模式是设计模式中的一种,主要目的是确保一个类只有一个实例,并提供一个全局访问点。

在Java中,实现单例模式的方法有五种:懒汉式、饿汉式、静态内部类、枚举和双重检查锁定。

懒汉式是使用最广泛的一种实现方式。

它通过在类内部定义一个静态私有变量,并在类的内部方法中进行实例的初始化。

当首次调用getInstance方法时,会创建实例并返回。

懒汉式的实现如下:class LazySingleton { private static LazySingleton singleton; private LazySingleton() {} public static LazySingleton getInstance() { if (singleton == null) { singleton = new LazySingleton(); } return singleton; }}饿汉式则是在类加载时即创建实例,这种方式保证了线程安全,但是可能造成资源浪费,因为类加载时实例就已经被创建了。

饿汉式的实现如下:class HungrySingleton { private static HungrySingleton singleton = new HungrySingleton(); private HungrySingleton() {} public static HungrySingleton getInstance() { return singleton; }}静态内部类的实现则是在第一次使用时才加载内部类,从而实现延迟加载。

这种方式既能保证线程安全,又不会在类加载时就创建实例。

静态内部类的实现如下:class InternalSingleton { private static class SingletonHolder { private final static InternalSingleton INSTANCE = new InternalSingleton(); } private InternalSingleton() {} public static InternalSingleton getInstance() { return ; }}枚举实现则通过枚举类型来保证实例的唯一性,并且可以防止反序列化重新创建新的对象。

枚举实现如下:enum EnumSingleton { INSTANCE; public void doSomeThing() { // do something }}最后一种是双重检查锁定,虽然在某些情况下可以提高性能,但在Java的当前内存模型中,这种方式是无效的。

双重检查锁定的实现如下:class LockSingleton { private volatile static LockSingleton singleton; private LockSingleton() {} public static LockSingleton getInstance() { if (singleton == null) { synchronized () { if (singleton == null) { singleton = new LockSingleton(); } } } return singleton; }}

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

53阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

44阅读

php一句话木马,一句话木马ctf

2026年10月05日

48阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

50阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

47阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

42阅读